package work.linruchang;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.*;
import work.linruchang.cmd.CMD;
import work.linruchang.cmd.CMDFactory;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Hello world!
 */
public class App {

    private static final String helpInfo = ResourceUtil.readStr("helpInfo.txt", CharsetUtil.CHARSET_UTF_8);

    public static void main(String[] args) {

        // 1. 参数解析
        KillProcessParam killProcessParam = argsConvertToKillProcessParam(args);

        // 2. 帮助文档
        if (killProcessParam.isHelpInfoFlag()) {
            Console.log(helpInfo);
            return;
        }

        // 3. 开始杀进程
        CMD cmd = CMDFactory.getCMD();
        Set<Integer> processIds = CollUtil.emptyIfNull(killProcessParam.getProcessIds());
        Set<Integer> ports = killProcessParam.getPorts();

        // Assert.isFalse(ObjUtil.isAllEmpty(processIds, ports), "缺乏待杀进程参数，请检查或运行命令查看帮助文档【java -jar kill-process.jar -h】");

        // 3.1 基于进程号杀进程
        if (CollUtil.isNotEmpty(processIds)) {
            Map<Integer, String> killProcessResultByProcesses = cmd.killProcesses(processIds);
            killProcessResultByProcesses.forEach((processId, result) -> {
                Console.log("杀死进程（{}）：【{}】", processId, result);
            });
        }


        // 3.2 基于端口号杀进程
        if (CollUtil.isNotEmpty(ports)) {
            Map<Integer, String> killProcessResultByPorts = cmd.killProcessByPorts(ports);
            killProcessResultByPorts.forEach((port, result) -> {
                Console.log("杀死端口号（{}）进程：【{}】", port, result);
            });
        }

        // 4. 端口号查进程号
        Set<Integer> p2PPorts = killProcessParam.getP2PProcessIds();
        Map<Integer, List<Integer>> p2PPortsResult = cmd.getProcessIds(p2PPorts);
        p2PPortsResult.forEach((port, process) -> {
            Console.log("端口号（{}）查找到的进程：{}", port, process);
        });


        // 5. 进程号查端口号
        Set<Integer> p2pProcessIds = killProcessParam.getP2pPorts();
        Map<Integer, List<Integer>> P2pProcessIdsResult = cmd.getPorts(p2pProcessIds);
        P2pProcessIdsResult.forEach((processId, port) -> {
            Console.log("进程（{}）查找到的端口号：{}", processId, port);
        });


        Console.log("\n命令执行完毕\n");

    }

    /**
     * 入参转成KillProcessParam请求对象
     *
     * @param args
     * @return
     */
    public static KillProcessParam argsConvertToKillProcessParam(String[] args) {
        args = ObjectUtil.defaultIfNull(args, new String[0]);
        KillProcessParam killProcessParam = new KillProcessParam();
        for (int i = 0; i < args.length; i = i + 2) {

            if (StrUtil.equalsAnyIgnoreCase(args[i], "help", "--help", "-h")) {
                killProcessParam.setHelpInfoFlag(true);
                break;
            }


            if (StrUtil.equalsAny(args[i], "-p", "--port", "port")) {
                Set<String> portStrs = Convert.toSet(String.class, ArrayUtil.get(args, i + 1));
                Set<Integer> ports = Convert.toSet(Integer.class, CollUtil.removeBlank(portStrs));
                killProcessParam.setPorts(ports);
            } else if (StrUtil.equalsAny(args[i], "-P", "--process", "process")) {
                Set<String> processStrs = Convert.toSet(String.class, ArrayUtil.get(args, i + 1));
                Set<Integer> processes = Convert.toSet(Integer.class, CollUtil.removeBlank(processStrs));
                killProcessParam.setProcessIds(processes);
            } else if (StrUtil.equalsAny(args[i], "-p2P", "--port2process", "port2process")) {
                Set<String> portStrs = Convert.toSet(String.class, ArrayUtil.get(args, i + 1));
                Set<Integer> ports = Convert.toSet(Integer.class, CollUtil.removeBlank(portStrs));
                killProcessParam.setP2PProcessIds(ports);
            } else if (StrUtil.equalsAny(args[i], "-P2p", "--process2port", "process2port")) {
                Set<String> processStrs = Convert.toSet(String.class, ArrayUtil.get(args, i + 1));
                Set<Integer> processes = Convert.toSet(Integer.class, CollUtil.removeBlank(processStrs));
                killProcessParam.setP2pPorts(processes);
            }

        }

        if(ObjUtil.isAllEmpty(killProcessParam.getP2PProcessIds(),killProcessParam.getP2pPorts(),killProcessParam.getPorts(),killProcessParam.getProcessIds())) {
            killProcessParam.setHelpInfoFlag(true);
        }

        return killProcessParam;
    }

}
